/*
 * @Author: Wangtao
 * @Date: 2021-04-09 17:00:33
 * @LastEditors: Wangtao
 * @LastEditTime: 2022-04-15 18:52:06
 */
import { VuexModule, Module, Mutation, Action, getModule } from 'vuex-module-decorators'
import { RouteConfig } from 'vue-router'
import { asyncRoutes, constantRoutes } from '@/router'
import { deepClone } from '@/utils/common'
import router from '@/router/handleRoute'
import store from '@/store'

const hasPermission = (roles: string[], route: RouteConfig) => {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

export const filterAsyncRoutes = (routes: RouteConfig[], roles: string[]) => {
  const res: RouteConfig[] = []
  routes.forEach(route => {
    const r = { ...route }
    if (hasPermission(roles, r)) {
      if (r.children) {
        r.children = filterAsyncRoutes(r.children, roles)
      }
      res.push(r)
    }
  })
  return res
}

export interface IPermissionState {
  routes: RouteConfig[]
  dynamicRoutes: RouteConfig[]
  roleRoutes: RouteConfig[]
}

@Module({ dynamic: true, store, name: 'permission' })
class Permission extends VuexModule implements IPermissionState {
  public routes: RouteConfig[] = []
  public dynamicRoutes: RouteConfig[] = []
  public roleRoutes: RouteConfig[] = []
  @Mutation
  private SET_ROUTES (routes: RouteConfig[]) {
    this.routes = constantRoutes.concat(routes)
    this.dynamicRoutes = routes
  }

  @Mutation
  private DEL_ROUTES (name: string) {
    this.routes = [...this.routes]
    try {
      const route = (asyncRoutes as any).find(item => item?.meta?.roles?.includes(name))
      route.meta.index = 1
      if (this.routes.findIndex(item => item?.meta?.roles?.includes(name)) > -1) {
        this.routes.splice(this.routes.findIndex(item => item?.meta?.roles?.includes(name)), 1)
      }
    } catch (error) {
      //
    }
  }

  @Mutation
  private ADD_ROUTES (name: string) {
    if (!store.state.common.session.user.limits.includes(name)) { // 没有权限时不添加一级菜单
      return
    }
    const route = (asyncRoutes as any).find(item => item?.meta?.roles?.includes(name))
    this.routes.push(route)
  }

  @Mutation
  public SET_ROLEROUTES (routes: RouteConfig[]) {
    this.roleRoutes = constantRoutes.concat(routes)
  }

  @Action
  public GenerateRoutes (roles: string[]) {
    // let accessedRoutes
    // if (roles.includes('admin')) {
    //   accessedRoutes = asyncRoutes
    // } else {
    //   accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
    // }
    const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
    this.SET_ROUTES(accessedRoutes)
    this.SET_ROLEROUTES(deepClone(accessedRoutes))
  }

  @Action
  public delRoutes (name) {
    this.DEL_ROUTES(name)
  }

  @Action
  public addRoutes (name) {
    this.ADD_ROUTES(name)
  }
}

export const PermissionModule = getModule(Permission)
